package com.ds.infrastructure.audit.collector.interceptor;

import com.ds.infrastructure.audit.collector.config.SSOConfig;
import com.ds.infrastructure.audit.collector.entity.UserInfo;
import com.ds.infrastructure.audit.collector.service.SSOService;
import com.ds.infrastructure.audit.collector.util.RequestUtils;
import com.ds.infrastructure.audit.common.constant.CommonConstant;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.stereotype.Component;
import org.springframework.web.filter.OncePerRequestFilter;

import javax.annotation.Resource;
import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpServletResponseWrapper;
import java.io.IOException;

/**
 * 作用：
 *
 * @author WeiShaoying
 * @date 2020/8/11
 */
@Component
@ConditionalOnProperty(name = "sso.enable", havingValue = "true")
@Slf4j
@SuppressWarnings("all")
public class AuthRequestFilter extends OncePerRequestFilter {

    private static final String STATIC_RESOURCE_REGEX = ".*\\.(ico|js|html|htm|png|css|woff2)$";

    @Resource
    private SSOService ssoService;

    @Resource
    private SSOConfig ssoConfig;

    public static final String R_APP = "/app";
    public static final String R_COLLECTOR = "/collector";


    @Override
    protected void doFilterInternal(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, FilterChain filterChain) throws ServletException, IOException {
        String requestUri = httpServletRequest.getRequestURI();
        log.info("Filter={}", requestUri);
        if (isAllowResource(requestUri)) {
            filterChain.doFilter(httpServletRequest, httpServletResponse);
            return;
        }
        UserInfo userInfo = auth(httpServletRequest);
        if (userInfo != null) {
            filterChain.doFilter(httpServletRequest, httpServletResponse);
        } else {
            HttpServletResponseWrapper wrapper = new HttpServletResponseWrapper(httpServletResponse);
            wrapper.sendRedirect(ssoConfig.getLoginUrl() + "?service=" + ssoConfig.getService());
        }
    }

    private UserInfo auth(HttpServletRequest request) {
        //从参数中获取
        String sid = RequestUtils.getAuthorization(request);
        if (StringUtils.isNotBlank(sid)) {
            return ssoService.getUserInfo(sid);
        }

        String auth = request.getHeader(CommonConstant.HTTP_HEADER_AUTHORIZATION);
        log.debug("auth: {}", auth);
        if (StringUtils.isEmpty(auth)) {
            Cookie[] cookies = request.getCookies();
            if (cookies == null) {
                return null;
            }
            for (Cookie cookie : cookies) {
                if ("sid".equals(cookie.getName())) {
                    auth = cookie.getValue();
                    break;
                }
            }
        }
        if (StringUtils.isEmpty(auth)) {
            return null;
        }
        return ssoService.getUserInfo(auth);
    }

    private boolean isAllowResource(String uri) {
        return (!uri.startsWith(R_APP) && !uri.startsWith(R_COLLECTOR)) || isStaticResource(uri) /*|| uri.startsWith(AdminConstant.URL_SSO)*/;
    }

    private boolean isStaticResource(String uri) {
        return StringUtils.isNotEmpty(uri) && uri.matches(STATIC_RESOURCE_REGEX);
    }

}
